#include "yocto/utest/run.hpp"
#include "kernel/driver.hpp"

#include "yocto/ios/ocstream.hpp"
#include "yocto/lua/lua-state.hpp"
#include "yocto/lua/lua-config.hpp"
#include "yocto/code/rand.hpp"

#include "yocto/math/ode/drvck.hpp"

using namespace yocto;

static inline void saveData( ios::ocstream &fp, const array<Real> &F )
{
	for( size_t i=1; i <= F.size(); ++i )
	{
		fp(" %g", F[i] );
	}
}

YOCTO_UNIT_TEST_IMPL(cell)
{
	_rand.wseed();
	
	if( argc <= 1 )
		throw exception("%s: need script.lua", argv[0] );
	
	Lua::State VM;
	lua_State *L = VM();
	Lua::Config::DoFile( L, argv[1] );
	
	Cell cell(L);
	cell.steadyState();
	
	
	//-- testing
	Solution       &dS    = cell.solutions[ Cell::idS ];
	const Solution &S_in  = cell.solutions[ Cell::iS_in ];
	const Solution &S_out = cell.solutions[ Cell::iS_out ];
	
	dS.zero();
	dS.addLeak(0, cell.Volume, S_in, S_out );
	for( EnzymeDB::iterator i = cell.enzymes.begin(); i != cell.enzymes.end(); ++i )
	{
		EnzymePtr &enz = *i;
		(void) enz->addRate(dS,0,0.0,S_in,S_out,cell);
	}
	std::cerr << "dS1=" << std::endl; dS.display( std::cerr );
	const Real I1 =  dS.sumCharge();
	cell.chemsys.updateRate(dS, 0.0, S_in);
	std::cerr << "dS2=" << std::endl; dS.display( std::cerr );
	const Real I2 = dS.sumCharge();
	std::cerr << "I = " << I1 << " / " << I2 << std::endl;

	
	return 0;
	
	Driver::Type odeint(1e-4);
	Driver::Init( odeint, cell);
	const Real dt = 60;
	Real       t  = 0;
	std::cerr << "-- Initialize Run..." << std::endl;
	const char fmt[] = " %.12e";
	{
		ios::ocstream fp("diff.dat", false );
		fp("#t");
		cell.solutions[ Cell::iS_in ].write_header(fp);
		fp(" Em");
		fp("\n");
		
		fp("0");
		cell.solutions[ Cell::iS_in ].write_values(fp,fmt);
		fp(fmt, cell.Em/1000.0 );
		fp("\n");
	}
	
	std::cerr << "-- Run..." << std::endl;
	for( size_t i=1;;++i )
	{
		const Real t_old = (i-1) * dt;
		t                = i*dt;
		Driver::Step( odeint, cell, t_old, t );
		
		std::cerr << "t=" << t << std::endl;
		{
			ios::ocstream fp("diff.dat", true );
			fp("%g", t );
			cell.solutions[ Cell::iS_in ].write_values(fp,fmt);
			fp(fmt, cell.Em/1000.0 );
			fp("\n");
		}
		if( t >= 5 * 3600 )
			break;
	}
	
	
}
YOCTO_UNIT_TEST_DONE()
